#include <iostream>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <jsoncpp/json/json.h>

using namespace std;

string username;

enum OP_TYPE
{
    Enter = 1,
    Register,
    Check,
    Schedule,
    Mine,
    Cancel,
    Leave
};
const int Offset = 2;

class socket_client
{
private:
    string ips;
    short port;
    int sockfd;

    bool dl_flg;

    //string username;
    string usertel;

    int user_op;

    bool running;

public:
    socket_client(string ip = "127.0.0.1", short p = 8080, bool dl_flg = false, int user_op = 0, bool running = true)
        : sockfd(-1), ips(ip), port(p), dl_flg(dl_flg), user_op(user_op), running(running) {}

    bool Connect_server();

    void print_info();

    void User_Register();

    void User_Login();

    void User_Show_ticket();

    void User_Subscrib_ticket();

    void User_Cancel_ticket();

    void User_Show_Sub_ticket();

    void Run();

    
};



void socket_client::print_info()
{
    if (dl_flg)
    {
        cout << "----已登录----用户名:" << username << "----" << endl;
        cout << "1:查看预约  2:预定  3:查看我的预约  4:取消预约  5:退出" << endl;
        cout << "-------------------------------------------------------" << endl;
        cout << "请输入选项编号: ";
        cin >> user_op;
        user_op += Offset;
    }

    else
    {
        cout << "-----未登陆-----游客-----" << endl;
        cout << "1:登陆  2:注册  3:退出" << endl;
        cout << "请输入选项编号: ";
        cin >> user_op;
        if (user_op == 3)
            user_op = Leave;
    }
}

bool socket_client::Connect_server()
{
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1)
    {
        cout << "create socket err" << endl;
        return false;
    }

    struct sockaddr_in saddr;
    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(port);
    if (inet_pton(AF_INET, ips.c_str(), &saddr.sin_addr) <= 0)
    {
        cerr << "Invalid address  not supported!" << endl;
        return false;
    }

    if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        cerr << "Connection failed!" << endl;
        return false;
    }

    cout << "Connected to server successfully!" << endl;
    return true;
}

void socket_client::Run()
{
    while (running)
    {
        print_info();
        switch (user_op)
        {
        case Enter:
            User_Login();
            break;
        case Register:
            User_Register();
            break;
        case Check:
            User_Show_ticket();
            break;
        case Schedule:
            User_Subscrib_ticket();
            break;
        case Mine:
            User_Show_Sub_ticket();
            break;
        case Cancel:
            User_Cancel_ticket();
            break;
        case Leave:
            running = false;
            break;
        default:
            cout << "输入无效" << endl;
            break;
        }
    }
}

void socket_client::User_Cancel_ticket()
{
    int yd_id=0,tk_id=0;
    Json::Value val;
    val["type"] = Cancel;
    cout<<"请输入要取消预约的yd_id: ";
    cin>>yd_id;
    cout<<"请输入要取消预约的tk_id: ";
    cin>>tk_id;

    val["yd_id"]=yd_id;
    val["tk_id"]=tk_id;
    send(sockfd, val.toStyledString().c_str(), strlen(val.toStyledString().c_str()), 0);

    char buff[128]={};
    int n=recv(sockfd, buff, 127, 0);
    if (n <= 0)
    {
        cout << "接收数据时发生错误或服务器关闭连接" << endl;
        return;
    }

    Json::Reader read;
    if (!read.parse(buff, val)) // 解析 JSON 数据
    {
        cout << "JSON 解析失败: " << read.getFormattedErrorMessages() << endl;
        return;
    }

    string st = val["status"].asString();
    if (st.compare("OK") != 0){
        cout<<"取消预约失败"<<endl;
        return;
    }

    cout<<"取消成功"<<endl;


    return;
}

void socket_client::User_Show_Sub_ticket()
{

    Json::Value val;
    val["type"] = Mine;
    val["tel"] = usertel;

    // 发送请求
    send(sockfd, val.toStyledString().c_str(), strlen(val.toStyledString().c_str()), 0);

    // 增加缓冲区大小
    char buff[128] = {};
    int n = recv(sockfd, buff, 127, 0);

    if (n <= 0)
    {
        cout << "接收数据时发生错误或服务器关闭连接" << endl;
        return;
    }

    Json::Reader read;
    if (!read.parse(buff, val)) // 解析 JSON 数据
    {
        cout << "JSON 解析失败: " << read.getFormattedErrorMessages() << endl;
        return;
    }

    string st = val["status"].asString();
    if (st.compare("OK") != 0)
    {
        cout << "暂无预约信息" << endl;
        return;
    }

    // 输出预约信息
    cout << "预约信息: " << endl;
    cout << "用户名: " << username << endl;
    cout << "预约ID: " << val["yd_id"].asString() << endl;
    cout << "票务ID: " << val["tk_id"].asString() << endl;
    cout << "手机号码: " << usertel << endl;
}

void socket_client::User_Subscrib_ticket()
{
    User_Show_ticket();
    cout << "请输入要预定的编号" << endl;
    int index = 0;
    cin >> index;

    Json::Value val;
    val["type"] = Schedule;
    val["tel"] = usertel;
    val["index"] = index;

    send(sockfd, val.toStyledString().c_str(), strlen(val.toStyledString().c_str()), 0);

    char buff[128] = {};
    int n = recv(sockfd, buff, 127, 0);
    if (n <= 0)
    {
        cout << "ser close" << endl;
        return;
    }

    Json::Reader read;
    if (!read.parse(buff, val))
    {
        cout << "Json 解析失败" << endl;
        return;
    }
    string st = val["status"].asString();
    if (st.compare("OK") != 0)
    {
        cout << "预约失败" << endl;
        return;
    }
    cout << "预约成功" << endl;
    return;
}

void socket_client::User_Show_ticket()
{
    Json::Value val;
    val["type"] = Check;
    send(sockfd, val.toStyledString().c_str(), strlen(val.toStyledString().c_str()), 0);

    char buff[4096] = {};
    int n = recv(sockfd, buff, 4095, 0);
    if (n <= 0)
        return;

    val.clear();
    Json::Reader read;
    if (!read.parse(buff, val))
    {
        cout << "Json 解析失败" << endl;
        return;
    }

    string st = val["status"].asString();
    if (st.compare("OK") != 0)
    {
        cout << "查询信息失败" << endl;
        return;
    }

    int count = val["count"].asInt();
    if (count == 0)
    {
        cout << "没有可预约的信息" << endl;
        return;
    }
    cout << " 编号 地点名称  总票数 已预定  时间" << endl;
    for (int i = 0; i < count; i++)
    {
        cout << "|"
             << val["info"][i]["tk_id"].asString() << "  "
             << val["info"][i]["addr"].asString() << "  "
             << val["info"][i]["max"].asString() << "  "
             << val["info"][i]["num"].asString() << "  "
             << val["info"][i]["use_date"].asString() << "| " << endl;
    }
}

void socket_client::User_Register()
{
    cout << "请输入用户手机号码：";
    cin >> usertel;

    cout << "请输入用户名: ";
    cin >> username;

    string passwd, tmp;
    cout << "请输入密码: ";
    cin >> passwd;

    cout << "请再次输入密码: ";
    cin >> tmp;

    if (usertel.empty() || username.empty())
    {
        cout << "手机或用户名不能为空" << endl;
        return;
    }

    if (passwd.compare(tmp) != 0)
    {
        cout << "密码不一致" << endl;
        return;
    }

    // 准备注册数据并发送给服务器
    Json::Value val;
    val["type"] = Register;
    val["user_tel"] = usertel;
    val["user_name"] = username;
    val["user_passwd"] = passwd;

    string data = val.toStyledString();
    send(sockfd, data.c_str(), data.size(), 0); // 发送注册请求

    // 接收服务器响应并打印
    char buff[256] = {0};
    if (recv(sockfd, buff, sizeof(buff) - 1, 0) <= 0)
    {
        cout << "Server closed connection" << endl;
        return;
    }

    // 打印接收到的数据
    cout << "Received from server: " << buff << endl;

    // 解析服务器返回的 JSON 数据
    Json::Value response;
    Json::Reader reader;
    if (!reader.parse(buff, response)) // 解析服务器响应
    {
        cout << "JSON 解析失败" << endl;
        return;
    }

    string status = response["status"].asString();
    if (status == "OK")
    {
        cout << "注册成功" << endl;
    }
    else
    {
        cout << "注册失败" << endl;
    }
}

void socket_client::User_Login()
{
    string tel, passwd;
    cout << "请输入手机号码: ";
    cin >> tel;
    cout << "请输入密码: ";
    cin >> passwd;

    if (tel.empty() || passwd.empty())
    {
        cout << "手机号或密码不能为空！" << endl;
        return;
    }

    Json::Value val;
    val["type"] = Enter;
    val["user_tel"] = tel;
    val["user_passwd"] = passwd;

    send(sockfd, val.toStyledString().c_str(), strlen(val.toStyledString().c_str()), 0);

    char buffer[256] = {};
    int n = recv(sockfd, buffer, 255, 0);
    if (n <= 0)
    {
        cout << "error" << endl;
        return;
    }

    val.clear();
    Json::Reader Read;
    if (!Read.parse(buffer, val))
    {
        cout << "解析Json失败" << endl;
        return;
    }

    string st = val["status"].asString();
    if (st.compare("OK") != 0)
    {
        cout << "登陆失败" << endl;
        return;
    }

    dl_flg = true;
    username = val["user_name"].asString();
    usertel = tel;

    cout << "登陆成功! " << endl;
    return;
}

int main()
{
    socket_client client("127.0.0.1", 8080);
    if (client.Connect_server())
    {
        client.Run();
    }

    return 0;
}